home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
MEM_UTL
/
SWEEP
/
SWEEP.DOC
next >
Wrap
Text File
|
1990-08-01
|
17KB
|
495 lines
Sweep Library User's Manual
Copyright (c) 1990 Eric Tauck
All Right Reserved
The Sweep Library is a library of routines for managing memory and
maintaining a heap. The advantage of the Sweep Library over the heap
routines built into Turbo Pascal or Turbo C is that the Sweep Library
never suffers from memory fragmentation. The Sweep Library is ideal
for applications that repeatedly allocate, deallocate, and resize
blocks of memory.
The Sweep Library is available for Turbo C and Turbo Pascal. The
Turbo C version should work with all versions of Turbo C and all
memory models except tiny. The Turbo C version may also work with
other compilers that support standard LIB files and Pascal calling
conventions. The Turbo Pascal version was compiled with Turbo Pascal
version 5.5 and should work with Turbo Pascal versions 5.0 and 5.5.
The Sweep Library is shareware. If you wish to continue using this
library after trying it out, please register your copy for $10 (US
funds, payable to Eric Tauck). For an additional $15 dollars (i.e., a
total of $25) you can receive the Sweep Library source code (for both
Turbo C and Turbo Pascal). The source code is written in TASM 2.0
assembly language. Both 5.25" and 3.5" disk formats are available.
Eric Tauck
1304 Deerpass Road
Marengo, IL 60152
U.S.A
Compuserve: 72457,1557
GEnie: E.TAUCK
Internet: 72457.1557@compuserve.com
Sweep Library Description
-------------------------
The necessary files for Turbo C are:
SWEEP.LIB
SWEEP.H
The Sweep Library routines are included in a Turbo C program by using
the #include statement and linking the library file with your compiled
program:
#include "sweep.h"
and compile as:
tcc myprog sweep.lib
The only file necessary for Turbo Pascal is:
SWEEP.TPU
The Sweep Library routines are included in a Turbo Pascal program by
using the USES statement:
USES Sweep;
A heap is created with the HeapInit or HeapInitBlk routines. These
routines require the address and size of a memory block in which to
create the heap. The farcoreleft and farmalloc in Turbo C provide
ideal functions for allocating a block of memory for the heap:
/* Turbo C */
#include "sweep.h"
void far *base; /* 'far' only for small/medium mdls */
unsigned long size;
size = farcoreleft(); /* bytes available */
base = farmalloc (size); /* allocate memory */
HeapInit (base, size); /* create heap */
Though you could use the MaxAvail and GetMem routines in Turbo Pascal,
you would be limited to a heap of 64K (because GetMem will not
allocate blocks larger than 64K). This limitation can be overcome by
using three special Turbo Pascal routines provided in the Sweep unit:
DosAvail, DosAlloc, and DosFree. These functions allocate memory
directly from the operating system rather than the Turbo Pascal heap
manager and are not restricted to 64K. Since the Turbo Pascal heap
manager usually takes all available memory, you must use the $M
directive to make some memory available:
{ Turbo Pascal }
{$M 16384,0,0} { tell TP not to use any extra mem. }
USES Sweep;
VAR
base: Pointer;
size: LongInt;
BEGIN
size := DosAvail; { bytes available }
base := DosAlloc (size); { allocate memory }
HeapInit (base, size); { create heap }
Once the heap has been created, you can allocate memory with HeapAlloc
and release memory with HeapFree. HeapAlloc does not return an
address to the allocated memory, but rather a 16-bit handle. This
handle type is called HeapHandle and is used by all the heap
management routines. Memory blocks are accessed by retrieving their
address with HeapAddr and assigning this address to a pointer:
/* Turbo C */
/* create an array and zero all elements */
/* the explicit fars are only needed for small or medium models */
typedef int ArrayType [1000];
HeapHandle MyArrayPtr;
ArrayType far *MyArray;
int i;
MyArrayPtr = HeapAlloc (sizeof (ArrayType)); /* allocate */
MyArray = (ArrayType far *)HeapAddr (MyArrayPtr); /* get address */
for (i = 0; i < 1000; i++) (*MyArray)[i] = 0; /* zero array */
{ Turbo Pascal }
{ create an array and zero all elements }
TYPE
ArrayType = ARRAY [1..1000] OF Integer;
VAR
MyArrayPtr: HeapHandle;
MyArray: ^ArrayType;
i: Integer;
BEGIN
MyArrayPtr := HeapAlloc (SizeOf (ArrayType)); { allocate }
MyArray := HeapAddr (MyArrayPtr); { get address }
FOR i := 1 TO 1000 DO MyArray^[i] := 0; { zero array }
A special handle value is used to indicate an error. In C it's called
SWEEP_NULL and in Pascal it's called SWEEP_NIL. You can also check
for an error by calling HeapResult.
When a memory block is allocated or resized, the address of other
blocks may change. This is a result of maintaining an unfragmented
heap. The address of a block returned by HeapAddr is only valid until
the next time the heap is manipulated.
A limitation of the Sweep Library heap routines is that there is a
fixed number of blocks that can be allocated. HeapInit sets the
maximum number of blocks to about 1/64 of the available memory space.
The maximum number of blocks can be explicitly defined with
HeapInitBlk.
You can use the Sweep Library pointer manipulation routines to access
data structures greater than 64K in Turbo Pascal. If you calculate
the 32 bit offset of an element within a large data structure, you can
add the offset to the base address with the PointerAdd function, for
instance:
{ Turbo Pascal }
{ create array of 50000 integers and zero all elements }
CONST
MyArrayDim = 50000;
MyArrayElem = SizeOf (Integer);
VAR
MyArrayPtr: HeapHandle;
IntPtr: ^Integer;
i: Word;
BEGIN
MyArrayPtr := HeapAlloc (MyArrayDim * MyArrayElem); { allocate }
FOR i := 1 TO 1000 DO
BEGIN
IntPtr := PointerAdd (HeapAddr (MyArrayPtr),
LongInt(i - 1) * LongInt(MyArrayElem));
IntPtr^ := 0;
END;
You can use the same technique to access large data structures in
Turbo C.
Sweep Routine Summary
---------------------
PointerNormal normalize a pointer
PointerDenormal denormalize a pointer
PointerAdd add an offset to a pointer
PointerSub subtract an offset from a pointer
PointerValue convert a pointer to a linear value
PointerDiff calculate the difference between two pointers
CopyForward forward copy a memory block
CopyBackward reverse copy a memory block
HeapInit initialize a heap
HeapInitBlk initialize a heap with a block count
HeapCurrent return the current heap address
HeapSelect switch to a new heap
HeapMemory return the bytes available
HeapBlocks return the blocks available
HeapShrink reduce the size of a heap
HeapExpand increase the size of a heap
HeapAlloc allocate a memory block
HeapResize resize a memory block
HeapFree free a memory block
HeapSize return the size of a memory block
HeapAddr return the address of a memory block
HeapResult return the error code of the last operation
DosAvail return available system memory (Turbo Pascal only)
DosAlloc allocate system memory (Turbo Pascal only)
DosFree free system memory (Turbo Pascal only)
Sweep Routine Descriptions
--------------------------
Though all the pointer values accepted and returned by the Turbo C
functions are listed as type 'far', all of the routines except
PointerDenormal (which always returns a far pointer) will also work
with huge pointers. A 'far' modifier for pointer variables is only
necessary when using the small or medium memory models. A 'huge' or
'near' modifier is never necessary.
Many of the Turbo C routines return a value when the Turbo Pascal
equivalents don't. Ignore any return value descriptions for Turbo
Pascal PROCEDURE types.
CopyForward
- void far * CopyForward (void far *d, void far *s, unsigned long c)
- PROCEDURE CopyForward (d, s: Pointer; c: LongInt)
Copy a contiguous block of memory. The block may be greater than
64K bytes. The copy operation is started from the beginning of the
block, so an overlapping copy will only work if the destination is
at a lower address than the source. If the source and destination
do not overlap, this function has the same effect as CopyBackward.
CopyBackward
- void far* CopyBackward (void far *d, void far *s, unsigned long c)
- PROCEDURE CopyBackward (d, s: Pointer; c: LongInt)
Copy a contiguous block of memory. The block may be greater than
64K bytes. The copy operation is started from the end of the block,
so an overlapping copy will only work if the destination is at a
higher address than the source. If the source and destination do
not overlap, this function has the same effect as CopyForward.
DosAlloc
- FUNCTION DosAlloc (s: LongInt): Pointer;
Allocate system memory. Memory must be made available using the $M
directive. For instance {$M 16000,4000,4000} allocates 16000 bytes
for the stack and 4000 bytes for the Turbo Pascal heap. All
remaining system memory may be allocated by DosAlloc. This function
is only available in Turbo Pascal.
DosAvail
- FUNCTION DosAvail: LongInt;
Return available system memory. Use this function find the largest
block available for DosAlloc. This function is only available in
Turbo Pascal.
DosFree
- PROCEDURE DosFree (p: Pointer);
Free allocated system memory. Use this function to release memory
allocated with DosAlloc. This function is only available in Turbo
Pascal.
PointerAdd
- void far * PointerAdd (void far *p, unsigned long o)
- FUNCTION PointerAdd (p: Pointer; o: LongInt): Pointer;
Add an offset to a far pointer. The resulting address is
normalized.
PointerDiff
- unsigned long PointerDiff (void far *p1, void far *p2)
- FUNCTION PointerDiff (p1, p2: Pointer): LongInt;
Calculate the difference between two far pointers. The result is a
standard 32 bit signed value (not a pointer).
PointerDenormal
- void far * PointerDenormal (void far *p)
- FUNCTION PointerDenormal (p: Pointer): Pointer;
Denormalize a far pointer. As much of the segment of an address as
possible is transferred to the offset. This function does the
opposite of PointerNormal. The result is always a far pointer, even
when using the huge memory model.
PointerNormal
- void far * PointerNormal (void far *p)
- FUNCTION PointerNormal (p: Pointer): Pointer;
Normalize a far pointer. As much of the offset of an address as
possible is transferred to the segment. This function does the
opposite of PointerDenormal.
PointerSub
- void far * PointerSub (void far *p, unsigned long o)
- FUNCTION PointerSub (p: Pointer; o: LongInt): Pointer;
Subtract an offset from a far pointer. The resulting address is
normalized.
PointerValue
- unsigned long PointerValue (void far *p)
- FUNCTION PointerValue (p: Pointer): LongInt;
Return the 32 bit linear value equivalent of a far pointer. This
function is used to calculate the difference between two far
pointers.
HeapAddr
- void far * HeapAddr (HeapHandle b)
- FUNCTION HeapAddr (b: HeapHandle): Pointer;
Return the address of a heap memory block.
HeapAlloc
- HeapHandle HeapAlloc (unsigned long s)
- FUNCTION HeapAlloc (s: LongInt): HeapHandle;
Allocate a memory block from the heap. Return the block handle or
SWEEP_NULL (Turbo C) or SWEEP_NIL (Turbo Pascal) if error. 's' is
the number of bytes to allocate.
HeapMemory
- unsigned long HeapMemory (void)
- FUNCTION HeapMemory: LongInt;
Return the total available bytes in the heap.
HeapBlocks
- unsigned HeapBlocks (void)
- FUNCTION HeapBlocks: Word;
Return the number of available memory blocks in the heap.
HeapCurrent
- void far * HeapCurrent (void)
- FUNCTION HeapCurrent: Pointer;
Return the address of the current heap.
HeapExpand
- void HeapExpand (unsigned long s)
- PROCEDURE HeapExpand (s: LongInt)
Increase the size of the current heap. The heap is expanded at its
end by 's' bytes. Note: You are responsible for making sure that
there is enough available memory to perform this operation.
HeapFree
- void HeapFree (HeapHandle b)
- PROCEDURE HeapFree (b: HeapHandle)
Free a heap memory block.
HeapInit
- void far * HeapInit (void far *h, unsigned long s)
- PROCEDURE HeapInit (h: Pointer; s: LongInt)
Initialize a heap at the given address. The minimum heap size is 12
bytes. The maximum number of blocks is calculated as the heap size
divided by 64 with a minimum of 32 and a maximum of about 21800.
The newly initialized heap becomes the current heap and the original
heap address is returned. The function HeapInitBlk is identical
except that the maximum number of memory blocks is specified by the
user rather than being calculated. 'h' is the base heap address and
's' is the number of bytes allocated to the heap.
HeapInitBlk
- void far * HeapInitBlk (void far *h, unsigned long s, unsigned b)
- PROCEDURE HeapInitBlk (h: Pointer; s: LongInt; b: Word)
Initialize a heap at the given address. The minimum heap size is 12
bytes. The maximum number of blocks may be adjusted down, so use
HeapBlocks to find the actual number initialized. The newly
initialized heap becomes the current heap and the original heap
address is returned. The function HeapInit is identical except that
the maximum number of blocks is calculated rather than being
specified by the user. 'h' is the base heap address, 's' is the
number of bytes allocated to the heap, and 'b' is the number of
blocks to assign to the heap.
HeapResize
- HeapHandle HeapResize (HeapHandle b, unsigned long s)
- PROCEDURE HeapResize (b: HeapHandle; s: LongInt)
Resize a heap memory block. Returns the block handle or SWEEP_NULL
if error.
HeapResult
- int HeapResult (void)
- FUNCTION HeapResult: Word;
Return the error code of the last heap operation (or zero if no
error). The error code is reset with each operation (including this
one). An error code of 1 is out of memory and 2 is out of memory
blocks. The symbolic constants SWEEP_NOERROR, SWEEP_OUTOFBLOCKS,
and SWEEP_OUTOFMEMORY have been defined to check for these return
values.
HeapSelect
- void far * HeapSelect (void far *h)
- PROCEDURE HeapSelect (h: Pointer)
Switch to a previously initialized heap. Returns the current heap
address.
HeapShrink
- void HeapShrink (unsigned long s)
- PROCEDURE HeapShrink (s: LongInt)
Decrease the size of the heap. The heap is adjusted at its end by
's' bytes. Note: the heap MUST have at least 's' bytes free.
HeapSize
- unsigned long HeapSize (HeapHandle b)
- FUNCTION HeapSize (b: HeapHandle): LongInt;
Return the size of a heap memory block.